Visual Graphic Library

Server Communications Overview

Namespace: $GG.server

The Gig Games JavaScript library provides a framework for developing and managing multiplayer games. It includes core functionalities and various specialized services to handle game state, player interactions, event broadcasting, and more. This documentation covers the $GG global object, detailing its public interface and usage guidelines.

Include In Html

<head>
    ...
    <script src="https://launch.gig.game/api/js?key={API KEY HERE}"></script>
    ...
</head>

Three Parts of a Gig Game

Gig Games are designed with three primary components in mind:

1. Console:

  • PC or Mobile Devices: In host-controlled games, this is typically a PC or laptop used to manage the game. In player-controlled games, this is the account owner's mobile device that can start and control games. Either way, this device manages the gameplay.
  • Technologies: Developed with HTML, CSS, and JavaScript.

2. Optional Controller:

  • Mobile Devices: Used by players invited to interact with the game.
  • Technologies: Developed with HTML, CSS, and JavaScript.
  • Optional Component: Not used in single-player games.

3. Optional Engine:

  • Maintains Game State: Capable of preserving a game state over extended periods, independent of an active host PC.
  • Network Efficiency: Reduces network lag by eliminating the need for round trips to a host console, providing a smoother gameplay experience.
  • Technologies: Can be developed in .NET or JavaScript.
  • Learn more about developing engines.

Controller and Host Console

SignalR is a library that makes it easy to add real-time web functionality to applications. This means it allows for instant messaging between the server and clients (like the game host and players) without needing to constantly refresh the page. It works by creating a persistent connection where the server can send messages to connected clients in real-time.

In our game application, SignalR is used to manage the communication between the host (the main game controller) and the players. We expose this functionality through the $GG.server namespace, making it simple to broadcast events or capture events that are broadcast to us. Here's how it works in simple terms:

  1. Broadcast Events: The host can send messages or updates to all players or specific players. For example, starting a new game round or updating scores.
  2. Capture Events: Players can send messages back to the host or other players. For example, when a player makes a move or submits an answer.

When the game host starts a game, it is assigned to a specific communications server within our server farm and creates a unique game code. This game code is essential for routing messages correctly and is automatically handled by the $GG library when included in your HTML.

Here’s a simplified flow:

  • Host Initialization: The host starts the game, gets assigned to a server, and creates a game code.
  • Player Join: Players enter this game code to join the game.
  • Real-Time Communication: Using SignalR, the host and players can now send and receive real-time updates and messages.

The $GG library manages this communication automatically, ensuring that all messages are sent to the correct devices using the game code. Authentication is built-in, ensuring that only the correct players and host (using their unique keys) can communicate within a game session.

Event Broadcast vs. Event Queueing

The $GG library supports two types of message transmission:

  1. Event Broadcast: This sends messages in real-time but discards them if the connection is lost. This is useful for non-critical updates, such as real-time notifications or status updates, where missing a message or two does not significantly impact the game.
  2. Event Queueing: This ensures that messages are delivered even if the connection drops. If a player's connection is lost, messages are queued and automatically sent once the connection is restored.

Guaranteed message queueing ensures message delivery but can introduce delays due to queue management. Unguaranteed broadcasting offers lower latency and immediate delivery, making it ideal for real-time updates where occasional message loss is acceptable. This approach enhances game responsiveness without the performance impact of queuing.

Example of Message Events

Below is an example demonstrating how to send event between controlers and hosts.

Host Code Example

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Host Console</title>
    <script src="https://launch.gig.game/api/js?key={YOUR_API_KEY_HERE}"></script>
    <script>
        document.addEventListener("DOMContentLoaded", function () {
            const playerSelect = document.getElementById('playerSelect');

            $GG.server.attachEvent("OnReady", () => {
                console.log("Host is ready");

                // Sync players with the host
                $GG.server.syncPlayersToHost();

                // Handle PlayerSessionSync event from us calling syncPlayersToHost
                $GG.server.attachEvent('PlayerSessionSync', (options) => {
                    const players = options.players;
                    players.forEach(player => {
                        addPlayerToDropdown(player);
                    });
                });

                // Listen for player sessions starting. This is an automatic event from the framework when a controler starts.
                $GG.server.attachEvent('PlayerSessionStart', (options, sourceType, source) => {
                    if (sourceType === "Player") {
                        addPlayerToDropdown(source);
                        alert(`Player joined: ${source.playerName}`);
                    }
                });

                // Listen for player sessions ending. This is an automatic event from the framework when a controler disconnects.
                $GG.server.attachEvent('PlayerSessionEnd', (options, sourceType, source) => {
                    if (sourceType === "Player") {
                        removePlayerFromDropdown(source);
                        alert(`Player left: ${source.playerName}`);
                    }
                });

                // Listen for player actions.  This is our custom event from the controller.
                $GG.server.attachEvent('PlayerAction', (options, sourceType, source) => {
                    if (sourceType === "Player") {
                        alert(`Received from player ${source.playerName}: ${options.message}`);
                    }
                });
            });

            function addPlayerToDropdown(player) {
                const option = document.createElement('option');
                option.value = player.playerKey;
                option.textContent = player.playerName;
                playerSelect.appendChild(option);
            }

            function removePlayerFromDropdown(player) {
                const options = playerSelect.options;
                for (let i = 0; i < options.length; i++) {
                    if (options[i].value === player.playerKey) {
                        playerSelect.remove(i);
                        break;
                    }
                }
            }

            function sendMessageToPlayer() {
                const selectedPlayerKey = playerSelect.value;
                if (selectedPlayerKey) {
                    $GG.server.broadcastToPlayer(selectedPlayerKey, 'HostMessage', { message: 'Hello from Host!' });
                } else {
                    alert('Please select a player to send a message.');
                }
            }

            window.sendMessageToPlayer = sendMessageToPlayer;
        });
    </script>
</head>
<!-- gg-gamekey is assigned in Gig Game HUD when you create an app to develop -->
<!-- gg-hostkey is assigned in Gig Game HUD when you create an app to develop -->
<body
	 gg-gamekey="{Key Assigned on App Creation}"
	 gg-hostkey="{Key Assigned on App Creation}"
	 gg-language="en">

    <h1>Host Console</h1>
    <label for="playerSelect">Select Player:</label>
    <select id="playerSelect">
        <option value="">--Select a Player--</option>
    </select>
    <button onclick="sendMessageToPlayer()">Send Message to Selected Player</button>
    <button onclick="sendMessageToPlayers()">Send Message to All Players</button>
</body>
</html>

Player Controller Code Example

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Player Controller</title>
    <script src="https://launch.gig.game/api/js?key={YOUR_API_KEY_HERE}"></script>
    <script>
        document.addEventListener("DOMContentLoaded", function () {
            $GG.server.attachEvent("OnReady", () => {
                console.log("Controller is ready");

                // Listen for messages from the host
                $GG.server.attachEvent('HostMessage', (options, sourceType, source) => {
                    if (sourceType === "Host") {
                        alert(`Received from host: ${options.message}`);
                    }
                });
            });

            function sendMessageToHost() {
                $GG.server.broadcastToHost('PlayerAction', { message: 'Hello from Player!' });
            }

            window.sendMessageToHost = sendMessageToHost;
            window.leaveGame = leaveGame;
        });
    </script>
</head>
<!-- gg-gamekey is assigned in Gig Game HUD when you create an app to develop -->
<!-- gg-playerkey is used for testing locally to simulate multiple players.  1 = Player 1, 2 = Player 2, ect.  -->
<body gg-gamekey="{Key Assigned on App Creation}"
      gg-playerkey="00000000-0000-0000-0000-000000000001"  
      gg-language="en">

    <h1>Player Controller</h1>
    <button onclick="sendMessageToHost()">Send Message to Host</button>
    <button onclick="leaveGame()">Leave Game</button>
</body>
</html>

Explanation

  1. Host Code:

    • When the host page is loaded and $GG is ready, it calls syncPlayersToHost to get all players who are already online.
    • When the PlayerSessionSync event is received, it adds the current waiting players to the dropdown list.
    • When an additional player joins (PlayerSessionStart), the player is added to the dropdown list, and an alert is displayed.
    • When a player leaves (PlayerSessionEnd), the player is removed from the dropdown list, and an alert is displayed.
    • When a player sends an action (PlayerAction), an alert is displayed with the player's message.
    • The addPlayerToDropdown function adds a player to the dropdown list.
    • The removePlayerFromDropdown function removes a player from the dropdown list.
    • The sendMessageToPlayer function sends a message to the selected player in the dropdown list.
    • The sendMessageToPlayers function broadcasts a message to all players.
  2. Player Controller Code:

    • When the controller page is loaded and $GG is ready, it raises a local OnReady event.
    • The connection to the server automatically causes a PlayerSessionStart event to be sent to the host.
    • It listens for HostMessage events and alerts the message from the host.
    • When the "Send Message to Host" button is clicked, it sends a PlayerAction event to the host.
    • When the browser is closed, it the connection disconnect automatically causes a PlayerSessionEnd event to the host.

Optional Game Engine

Game engines are optional but offer significant advantages for managing game state and enhancing communication efficiency. By running directly on Gig Games servers, game engines can preserve the game state over extended periods, independent of an active host PC. This architecture ensures continuity and enhances the gaming experience by reducing latency, as data doesn’t need to travel back and forth between the server and a host PC.

Game engines can be a more advanced topic, with a detailed discussion available here.


Third Party APIs (AJAX)

Third-party APIs can be called from both controllers and hosts in Gig Games applications. However, directly embedding API keys within JavaScript code presents a significant security risk, as it exposes the keys to potential misuse or unauthorized access.

Secure API Key Management

To mitigate this security concern, Gig Games provides a secure way to manage and use third-party API keys through the Gig Games Hud Application Editor. This approach ensures that API keys are kept secure and are not exposed in the client-side code.

How It Works

  1. Defining API Keys:

    • In the Gig Games Hud Application Editor, you can define your third-party API keys. These keys are securely stored on the Gig Games server.
  2. Using Placeholders:

    • Instead of embedding the actual API keys in your JavaScript code, you use placeholders. A placeholder is a string in the format {YOUR_KEY_NAME}, where YOUR_KEY_NAME is the name you've assigned to your API key in the Hud Application Editor.
  3. Automatic Key Replacement:

    • When you make an AJAX call using the ggAjaxService class, the Gig Games server intercepts the request. It automatically replaces the placeholders with the actual API keys stored on the server before making the call to the third-party API.
  4. Example:

    • Suppose you have an API key named MY_API_KEY stored in the Hud Application Editor. You can use it in your AJAX call as follows:
      ajax.ajax({
          url: "https://api.thirdparty.com/data?apiKey={MY_API_KEY}",
          method: "GET",
          headers: {
              "Content-Type": "application/json"
          },
          data: null
      }).then(response => {
          console.log("Data received:", response);
      }).catch(error => {
          console.error("Error calling third-party API:", error);
      });
      
    • When the Gig Games server receives this request, it replaces {MY_API_KEY} with the actual API key before forwarding the request to the third-party API.

Image Uploads

Both hosts and players in Gig Games can upload images, enhancing the interactive experience. These images are securely stored on the Gig Games server and are readily accessible to the game host for download and future use. This ensures that all uploaded images remain safe and can be easily managed by the host, contributing to a more personalized and dynamic gaming environment. The process guarantees that hosts can leverage these images effectively during gameplay, adding to the overall engagement and customization of the game.